package com.yang.interceptor;

import com.yang.exception.BaseException;
import com.yang.utils.JwtUtil;
import com.yang.utils.ThreadLocalUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
import java.util.Map;
import java.util.Objects;

@Component
public class JwtInterceptor implements HandlerInterceptor {
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){
//        System.out.println(request.getRequestURI());
        //判断当前拦截到的是Controller的方法还是其他资源
        if (!(handler instanceof HandlerMethod)) {
            //当前拦截到的不是动态方法，直接放行
            return true;
        }
		//从请求头获取令牌
        String token=request.getHeader(JwtUtil.tokenName);
        try {
            //判断是否携带令牌
            if (StringUtils.isEmpty(token)){

                Enumeration<String> headerNames = request.getHeaderNames();
                while (headerNames.hasMoreElements()){
                    String element = headerNames.nextElement();
                    System.out.println(element+":"+request.getHeader(element));
                }

                throw new Exception("未携带JWT令牌");
            }

            //解析令牌
            Map<String,Object> map= JwtUtil.parseJWT(token);
            //判断令牌是否有效
            if (map==null){
                throw new Exception("JWT令牌有误");
            }

            Long userId= Long.valueOf(map.get("id").toString());

            // 获取用户id,判断在redis中有当前令牌，有证明处于登陆状态，否则处于离线状态,令牌不一致证明令牌有问题
            String value = (String) redisTemplate.opsForValue().get("userId:"+userId.toString());
            if (Objects.isNull(value)){
                throw new BaseException("用户未登录");
            }
            if (!value.equals(token)){
                System.out.println("前端jwt:"+token);
                System.out.println("redis jwt:"+value);
                throw new BaseException("令牌有问题");
            }
            //将用户id存入ThreadLocal
            ThreadLocalUtil.set(userId);

        }catch (Exception e){
            //出现异常，拦截，设置状态码为401
            response.setStatus(401);
            throw new BaseException(e.getMessage());
        }
        return true;
    }
}